'''
This module provides support for RDFwSchema
'''
from BeautifulSoup import BeautifulSoup, NavigableString, Tag
from rdflib import Namespace
import simplejson

INSTANCEURI = 'http://rdfw.org/Instance'
CLASSURI = 'http://rdfw.org/Class'
IDURI = 'http://rdfw.org/Id'
DATAURI = 'http://rdfw.org/DataProperty'
OBJECTURI = 'http://rdfw.org/ObjectProperty'
TERMURI = 'http://rdfw.org/RDFTerminate'
STOPURI = 'http://rdfw.org/stopUri'
STARTURI = 'http://rdfw.org/startUri'
STOPALL = 'http://rdfw.org/stopAll'
NS		= 'http://rdfw.org/Namespace'
ROOTURI		= 'http://rdfw.org/rootUri'

class RdfwSchemaException(Exception):pass

class RdfwSchema:
	'''
	Schema contains details of a particular RDFw Schema
	'''
	def __init__(self):
		self.classes = []
		self.termUri = ''
		self.startUri = []
		self.stopUri = []
		self.stopAll = False
		self.ns = None			#namespace
		self.rootUri = None		#the uppermost page URI that should be processed
	
	def dumpjson(self):
		json = {}
		json['termUri'] = self.termUri
		json['startUri'] = self.startUri
		json['stopUri'] = self.stopUri
		json['stopAll'] = self.stopAll
		json['ns'] = self.ns
		json['classes'] = [x.dump() for x in self.classes]
		return simplejson.dumps(json)
	
	def appendClass(self,prop):
		self.classes.append(prop)
	
class RdfwClass:
	
	def __init__(self,classuri):
		self.classUri = classuri
		self.dataUris = []
		self.objectUris = []

	def dump(self):
		d = {}
		d['classUri'] = self.classUri
		d['dataUri'] = self.dataUris
		d['objectUri'] = self.objectUris
		return d


def getNextUri(frag, uri):
	'''
	Given a BS html frag, return the next URI or None if not found
	'''
	links = frag.findAll('a',href=True) # ensure there's an href attribute
	gotcha = False
	#print links
	#print uri	
	for link in links:
		if gotcha:
			return link['href']
		if link['href']==uri:
			gotcha = True
	return None

def getNextUris(frag, uri, stoplist):
	data = []
	locs = frag.findAll('a',href=uri)
	#print locs
	#print
	for loc in locs:		
		#print loc.parent.parent
		while True:
			loc = loc.findNext('a',href=True)
			if loc == None: break
			try:
				if loc['href'] in stoplist: break
			except (KeyError):
				break
			data.append(loc['href'])
		
	return data


def parseHTML(html):
	
	soup = BeautifulSoup(html)
	#1st Test - get data following a Data Property tag
	print 'RDFwSchema from:', soup.head.title.string
	print
	
	schema = RdfwSchema()
	schema.termUri = getNextUri(soup,TERMURI)
	schema.startUri = getNextUris(soup, STARTURI,
						   [INSTANCEURI,CLASSURI,DATAURI,OBJECTURI,TERMURI,STOPURI,STARTURI,STOPALL] )
		
	schema.stopUri = getNextUris(soup, STOPURI,
						   [INSTANCEURI,CLASSURI,DATAURI,OBJECTURI,TERMURI,STOPURI,STARTURI] )
	
	schema.rootUri = getNextUri(soup,ROOTURI)
	if not schema.rootUri:
		raise RdfwSchemaException('No root URI was found in RDFW schema')
	
	if STOPALL in schema.stopUri:
		schema.stopAll = True
	schema.ns = Namespace(getNextUri(soup,NS))

	#this can refactor into getNextUris method WHEN this is turned into a class method
	for i in range(0, len(schema.startUri)):
		if schema.startUri[i][:7] != 'http://':
			schema.startUri[i] = schema.ns[schema.startUri[i]]
	for i in range(0, len(schema.stopUri)):
		if schema.stopUri[i][:7] != 'http://':
			schema.stopUri[i] = schema.ns[schema.stopUri[i]]	



		
	#Classes & Properties
	lists = soup.findAll('ul')
	for list in lists:
		items = list.findAll('li')
		for item in items:
			# first we need the classuri
			cls = getNextUri(item,CLASSURI)
			if cls != None:
				rdfwclass = RdfwClass( cls )#RdfwClass(cls.findNextSibling('a')['href'])
				#now we look for the properties
				propitems = item.findAll('li')
				for propitem in propitems:
					dprop = getNextUri(propitem,DATAURI)
					if dprop:
						rdfwclass.dataUris.append( dprop )
					oprop = getNextUri(propitem,OBJECTURI)
					if oprop:
					   rdfwclass.objectUris.append( oprop )
										 
				schema.appendClass(rdfwclass)
				
	return schema

